package com.ship.dispatch.bpm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.uuid.impl.UUIDUtil;
import com.ship.common.core.enums.MessageTypeEnum;
import com.ship.common.core.enums.ModuleUrlEnum;
import com.ship.common.core.exception.BusException;
import com.ship.common.core.utils.DateUtils;
import com.ship.common.core.web.domain.BaseResultCode;
import com.ship.common.core.web.domain.JsonResult;
import com.ship.common.core.utils.DateUtil;
import com.ship.common.security.utils.SecurityUtils;
import com.ship.dispatch.bean.*;
import com.ship.dispatch.bean.bpm.BpmJsonModelDO;
import com.ship.dispatch.bean.fob.Record;
import com.ship.dispatch.bean.fob.SpFobFileRecord;
import com.ship.dispatch.bean.fob.SpFobSubleaseStart;
import com.ship.dispatch.bean.orderPay.ConFiles;
import com.ship.dispatch.bean.orderPay.SpPaymentOrder;
import com.ship.dispatch.bpm.factory.BpmServiceFactory;
import com.ship.dispatch.bpm.service.BpmProcessDefinitionService;
import com.ship.dispatch.bpm.service.ProcessInstanceService;
import com.ship.dispatch.bpm.utils.JsonUtils;
import com.ship.dispatch.bpm.vo.BpmStartVO;
import com.ship.dispatch.mapper.bpm.BpmJsonModelMapper;
import com.ship.dispatch.mapper.fob.SpFobJsfhccbItemsMapper;
import com.ship.dispatch.service.*;
import com.ship.dispatch.service.bpm.BpmInstanceServiceApi;
import com.ship.dispatch.service.fob.FobService;
import com.ship.dispatch.service.fob.RecordService;
import com.ship.dispatch.service.fob.SpFobSubleaseStartService;
import com.ship.dispatch.service.orderPay.SpPaymentOrderService;
import com.ship.dispatch.service.shipBusiness.SmShipReportService;
import com.ship.system.api.ConBpmResultService;
import com.ship.system.api.RemoteMessageSendService;
import com.ship.system.api.domain.SysMessageSend;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.engine.IdentityService;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngines;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.Model;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.idm.api.Group;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 *@title ProcessInstanceServiceImpl
 *@description
 *@author yl
 *@create 2023/12/13
 */
@Service
public class ProcessInstanceServiceImpl extends BpmServiceFactory implements ProcessInstanceService {
    @Autowired
    @Lazy
    SpDispatchSchemeExecuteService spDispatchSchemeExecuteService;

    @Autowired
    SpDispatchSchemeDetailService spDispatchSchemeDetailService;

    @Autowired
    SpArrangeSchemeDetailService spArrangeSchemeDetailService;

    @Autowired
    RecordService recordService;
    @Autowired(required = false)
    SpFobJsfhccbItemsMapper spFobJsfhccbItemsMapper;

    @Resource
    BpmJsonModelMapper bpmJsonModelMapper;

    @Autowired
    BpmProcessDefinitionService processDefinitionService;

    @Autowired
    ConShippingService conShippingService;

    @Autowired
    SpFobSubleaseService spFobSubleaseService;

    /**
     * 根据流程定义ID启动流程实例
     *
     * @param processKey 流程定义Id
     * @param processKey 流程变量
     * @param businessKey 业务id
     * @return
     */
    @Override
    public JsonResult createProcessInstance(String processKey, Map<String, Object> params,String businessKey) {

        BpmJsonModelDO jsonModelDO = bpmJsonModelMapper.selectOne(new LambdaQueryWrapper<BpmJsonModelDO>().eq(BpmJsonModelDO::getBpmKey,processKey));
        Model model =  repositoryService.getModel(jsonModelDO.getDeployId());
        ProcessDefinition processDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
        // 活动流程定义
        //ProcessDefinition processDefinition =repositoryService.createProcessDefinitionQuery().processDefinitionKey(processKey).latestVersion().singleResult();

        if(processDefinition == null){
            return JsonResult.failed("流程定义不存在，请联系管理员确认后重新发起");
        }
        //TODO:后期从登录账号中获取登录人信息
        params.put("initiator","1");
        params.put("_FLOWABLE_SKIP_EXPRESSION_ENABLED", true);
        ProcessInstance instance = runtimeService.startProcessInstanceById(processDefinition.getId(), businessKey, params);
        // 设置流程名字
        runtimeService.setProcessInstanceName(instance.getId(), processDefinition.getName());
        return JsonResult.success(instance.getId());
    }

    @Transactional
    @Override
    public String createProcessInstance2(String processKey, Map<String, Object> params, String businessKey) {
        BpmJsonModelDO jsonModelDO = bpmJsonModelMapper.selectOne(new LambdaQueryWrapper<BpmJsonModelDO>().eq(BpmJsonModelDO::getBpmKey,processKey));
        Model model =  repositoryService.getModel(jsonModelDO.getDeployId());
        ProcessDefinition processDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
        // 活动流程定义
        //ProcessDefinition processDefinition =repositoryService.createProcessDefinitionQuery().processDefinitionKey(processKey).latestVersion().singleResult();

        //TODO:后期从登录账号中获取登录人信息
        params.put("initiator","1");
        params.put("_FLOWABLE_SKIP_EXPRESSION_ENABLED", true);
        params.put("startUserId",SecurityUtils.getUsername());
        params.put("startUserName",SecurityUtils.getUsername());
        /*if(SecurityUtils.getLoginUser()!=null && SecurityUtils.getLoginUser().getSysUser()!=null){
            params.put("startUserName",SecurityUtils.getLoginUser().getSysUser().getNickName());
        }*/
        ProcessInstance instance = runtimeService.startProcessInstanceById(processDefinition.getId(), businessKey, params);
        // 设置流程名字
        runtimeService.setProcessInstanceName(instance.getId(), processDefinition.getName());
        return instance.getId();
    }

    @Override
    public void delete(String processKey) {

    }
    /**
     * 激活或挂起流程实例
     *
     * @param state      状态
     * @param instanceId 流程实例ID
     */
    @Override
    public void updateProcessInstanceState(Integer state, String instanceId) {
        // 激活
        if (state == 1) {
            runtimeService.activateProcessInstanceById(instanceId);
        }
        // 挂起
        if (state == 2) {
            runtimeService.suspendProcessInstanceById(instanceId);
        }
    }
    /**
     * 删除流程实例ID
     *
     * @param instanceId   流程实例ID
     * @param deleteReason 删除原因
     */
    @Override
    public void delete(String instanceId, String deleteReason) {
        // 查询历史数据
        HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(instanceId);
        if (historicProcessInstance.getEndTime() != null) {
            historyService.deleteHistoricProcessInstance(historicProcessInstance.getId());
            return;
        }
        // 删除流程实例
        runtimeService.deleteProcessInstance(instanceId, deleteReason);
        // 删除历史流程实例
        historyService.deleteHistoricProcessInstance(instanceId);
    }

    @Resource
    RemoteMessageSendService remoteMessageSendService;
    @Transactional
    @Override
    public JsonResult<String> createProcessInstance(BpmStartVO bpmStartVO) {
        SpArrangeSchemeDetail spArrangeSchemeDetail = spArrangeSchemeDetailService.getById(bpmStartVO.getBusinessKey());
        if(spArrangeSchemeDetail.getImo().indexOf("virtualShip") > -1){
            return JsonResult.failed("船舶为虚拟船，该方案不能下发，请绑定船运合同，或调度优化，使用现有船只来进行运输！");
        }

        List<SpDispatchSchemeExecute> executes = spDispatchSchemeExecuteService.list(new LambdaQueryWrapper<SpDispatchSchemeExecute>().eq(SpDispatchSchemeExecute::getArrangeSchemeDetailId,bpmStartVO.getBusinessKey()).eq(SpDispatchSchemeExecute::getStatus,0));
        if(executes.size()>0){
            return JsonResult.failed("当前业务已启动流程，请勿重复发起");
        }
        if(bpmStartVO.getAssigner()==null){
            return JsonResult.failed("当前任务未设置业务执行人，请设置后重写执行");
        }
        String processKey = bpmStartVO.getProcessKey()!=null && bpmStartVO.getProcessKey()!=""? bpmStartVO.getProcessKey():getBpmKey(spArrangeSchemeDetail);
        if(processKey==null){
            return JsonResult.failed("当前业务未匹配流程执行规则，请确认后重新发起");
        }
        bpmStartVO.setProcessKey(processKey);
        // 创建候选组
        ProcessDefinition processDefinition =repositoryService.createProcessDefinitionQuery().processDefinitionKey(bpmStartVO.getProcessKey()).latestVersion().singleResult();
        if(processDefinition == null){
            return JsonResult.failed("流程定义不存在，请联系管理员确认后重新发起");
        }
        if(spArrangeSchemeDetail==null){
            return JsonResult.failed("调度方案不存，请确认后重新发起");
        }
        SpDispatchSchemeDetail spDispatchSchemeDetail = null;
        if(spArrangeSchemeDetail.getDispatchSchemeDetailId()!=null){
            spDispatchSchemeDetail = spDispatchSchemeDetailService.getById(spArrangeSchemeDetail.getDispatchSchemeDetailId());
        }

        //String processKey =bpmStartVO.getProcessKey();
        Map<String,Object> params = new HashMap<>();
        params.put("assigeners",bpmStartVO.getAssigner());
        //TODO:后期从登录账号中获取登录人信息
        params.put("initiator", SecurityUtils.getStringUserId());
        params.put("businessKey", bpmStartVO.getBusinessKey());
        if(spDispatchSchemeDetail!=null){
            Map<String,String> tempMap = JsonUtils.jsonToMap(JsonUtils.objectToJson(spDispatchSchemeDetail),String.class);
            params.putAll(tempMap);
        }else {
            Map<String,String> tempMap = JsonUtils.jsonToMap(JsonUtils.objectToJson(spArrangeSchemeDetail),String.class);
            params.putAll(tempMap);
        }
        params.put("_FLOWABLE_SKIP_EXPRESSION_ENABLED", true);
        ProcessInstance instance = runtimeService.startProcessInstanceById(processDefinition.getId(), bpmStartVO.getBusinessKey().toString(), params);
        // 设置流程名字
        runtimeService.setProcessInstanceName(instance.getId(), processDefinition.getName());
        // 绑定方案单据
        SpDispatchSchemeExecute execute = new SpDispatchSchemeExecute();
        if(spDispatchSchemeDetail!=null){
            BeanUtils.copyProperties(spDispatchSchemeDetail,execute);
            execute.setSchemeDetailId(spDispatchSchemeDetail.getId());
        }else {
            BeanUtils.copyProperties(spArrangeSchemeDetail,execute);
        }
        execute.setProcessInstanceId(instance.getId());
        execute.setId(null);
        execute.setStatus(0);
        execute.setSchemeDeliveryTime(new Date());
        execute.setAssigeners(bpmStartVO.getAssigner());
        execute.setArrangeSchemeDetailId(bpmStartVO.getBusinessKey());
        spDispatchSchemeExecuteService.save(execute);

        

        Record record = new Record();
        record.setSchemeDetailId(bpmStartVO.getBusinessKey());
        record.setServiceId(instance.getId());
        record.setProceeInstanceId(instance.getId());
        record.setBacthId("start");
        record.setRemark("开启船运执行任务");
        record.setCreateBy(SecurityUtils.getUsername());
        record.setCreateDate(new Date());
        recordService.save(record);

        SysMessageSend messageSend = new SysMessageSend();
        messageSend.setMessageUrl(ModuleUrlEnum.CYZXXQ.getUrl()+"processInstanceId="+execute.getProcessInstanceId()+"&id="+execute.getId()+"&schemeDetailId="+execute.getSchemeDetailId());
        messageSend.setMessageType(MessageTypeEnum.MESSAGE_TYPE_22.getCode());
        messageSend.setContentParam(new String[]{execute.getVoyageNo()});
        //messageSend.setCompareType(5);
        List<String> users = Arrays.stream(bpmStartVO.getAssigner().split(",")).collect(Collectors.toList());
        messageSend.setOtherUsernameList(users);
        remoteMessageSendService.messageSend(messageSend);
        return JsonResult.success(instance.getId());
    }


    public String getBpmKey(SpArrangeSchemeDetail detail){
        // 默认fob001
        String key =null;
        // 贸易类型

        // 贸易模式
        String tradeModel = null;
        String sellerTradeModel = null;
        // 交易类型
        String deliveryType = null;
        String sellerDeliveryType = null;
        if(detail.getResourceContract()!=null){
           Map<String,Object> map = spFobJsfhccbItemsMapper.getResouceMainContract(detail.getResourceContract());
           if(map!=null && map.containsKey("trade_model") && map.get("trade_model")!=null){
               tradeModel = map.get("trade_model").toString();
           }
            if(map!=null && map.containsKey("delivery_type") && map.get("delivery_type")!=null){
                deliveryType = map.get("delivery_type").toString();
            }
        }
        if(detail.getSellerResourceContract()!=null){
            Map<String,Object> map = spFobJsfhccbItemsMapper.getResouceMainContract(detail.getSellerResourceContract());
            if(map!=null && map.containsKey("trade_model") && map.get("trade_model")!=null){
                sellerTradeModel = map.get("trade_model")+"";
            }
            if(map!=null && map.containsKey("delivery_type") && map.get("delivery_type")!=null){
                sellerDeliveryType = map.get("delivery_type")+"";
            }
        }
        /**
         * 1. 有资源合同·采购
         * 2. 无资源合同·销售（说明未销售，应该回国）
         * 3. 采购贸易模式：采购
         * 4. 采购交付方式：FOB
         * 匹配该流程
         */
        if(detail.getResourceContract()!=null && detail.getSellerResourceContract()==null && deliveryType!=null && "1".equals(deliveryType) && tradeModel!=null && "1".equals(tradeModel)){
            key = "FOB001v1";
        }
        /**
         * 1. 有资源合同·采购
         * 2. 有资源合同·销售
         * 3. 采购贸易模式：采购
         * 4. 销售贸易模式；销售
         * 5. 采购交付方式：FOB
         * 6. 销售交付方式：DES
         * 匹配该流程
         * 1. 有资源合同·采购
         * 2. 有资源合同·销售
         * 3. 采购贸易模式：采购
         * 4. 销售贸易模式：返装销售
         * 5. 采购交付方式：FOB
         * 6. 销售交付方式：DES
         * 匹配该流程
         * fob001
         */
        else if(detail.getResourceContract()!=null && detail.getSellerResourceContract()!=null && tradeModel!=null && "1".equals(tradeModel)
                && sellerTradeModel!=null && ("2".equals(sellerTradeModel))
                && deliveryType!=null && "1".equals(deliveryType)
                && sellerDeliveryType!=null && "2".equals(sellerDeliveryType)
        ){
            key = "FOB001v1";
        }
        /**
         * 1. 有资源合同*采购
         * 2. 有资源合同*销售
         * 3. 采购贸易模式：采购
         * 4. 销售贸易模式：销售 / 返装销售
         * 5. 采购交付方式：FOB
         * 6. 销售交付方式：FOB
         * 匹配该流程 fob002
         */
        else if(detail.getResourceContract()!=null && detail.getSellerResourceContract()!=null && tradeModel!=null && "1".equals(tradeModel)
                && sellerTradeModel!=null && ("2".equals(sellerTradeModel))
                && deliveryType!=null && "1".equals(deliveryType)
                && sellerDeliveryType!=null && "1".equals(sellerDeliveryType)
        ){
            key = "Fob002V1";
        }
        /**
         * 1. 无资源合同*采购（说明是海油自有的 LNG）
         * 2. 有资源合同*销售
         * 3. 无采购贸易模式
         * 4. 销售贸易模式：返装销售
         * 5. 无采购交付方式
         * 6. 销售交付方式：FOB
         * fob003
         */
        else if(detail.getSellerResourceContract()!=null
                && sellerTradeModel!=null && "3".equals(sellerTradeModel)
                && sellerDeliveryType!=null && "1".equals(sellerDeliveryType)
        ){
            key = "Fob003v1";
        }else if(detail.getSellerResourceContract()!=null
                && sellerTradeModel!=null && "3".equals(sellerTradeModel)
                && sellerDeliveryType!=null && "2".equals(sellerDeliveryType)
        ){
            key = "FOB004v1";
        }
        return key;
    }


    @Override
    public JsonResult cacenProcessInstance(String processInstaneId) {
        ProcessInstance instance =  runtimeService.createProcessInstanceQuery().processInstanceId(processInstaneId).singleResult();
        if (instance == null) {
            return JsonResult.failed("流程实例不存在，无法取消");
        }
        runtimeService.deleteProcessInstance(processInstaneId, "主动取消流程");
        SpDispatchSchemeExecute dispatchSchemeExecute = spDispatchSchemeExecuteService.getExceuteByInstanceId(processInstaneId);
        if(dispatchSchemeExecute!=null){
            dispatchSchemeExecute.setStatus(-1); // 中止流程
            spDispatchSchemeExecuteService.updateById(dispatchSchemeExecute);
        }
        return JsonResult.success();
    }

    @Resource
    @Lazy
    ConBpmResultService conBpmResultService;

    @Resource
    @Lazy
    FobService fobService;
    @Resource
    @Lazy
    SpDispatchService spDispatchService;
    @Resource
    @Lazy
    SpArrangeSchemeService spArrangeSchemeService;
    @Resource
    @Lazy
    SpPaymentOrderService spPaymentOrderService;

    @Resource
    @Lazy
    SmShipCrewService smShipCrewService;

    @Resource
    @Lazy
    SmShipReportService smShipReportService;

    @Resource
    @Lazy
    SpOverhaulService spOverhaulService;

    @Autowired
    ConFilesService conFilesService;
    @Transactional
    @Override
    public void cancelProcessInstanceId(String processsInstanceId) {
        HistoricProcessInstance processInstance =  historyService.createHistoricProcessInstanceQuery().processInstanceId(processsInstanceId).singleResult();
                //runtimeService.createProcessInstanceQuery().processInstanceId(processsInstanceId).singleResult();
        if (processInstance == null) {
            throw new BusException("流程实例不存在，无法取消", BaseResultCode.GENERAL_ERROR);
        }
        List<HistoricTaskInstance>  tasks = historyService.createHistoricTaskInstanceQuery().finished().processInstanceId(processsInstanceId).list(); // 已完成
        if(tasks.size()>0){
            throw new BusException("当前流程已存在审批记录，无法取消", BaseResultCode.GENERAL_ERROR);
        }
        runtimeService.deleteProcessInstance(processsInstanceId, "主动取消流程");
        //调用任务状态处理逻辑
        if(processInstance.getProcessDefinitionKey().startsWith("con") || processInstance.getProcessDefinitionKey().startsWith("saveClause")){
            conBpmResultService.updateConResult(processInstance.getBusinessKey(),0,processInstance.getProcessDefinitionKey());
        }else if(processInstance.getProcessDefinitionKey().startsWith("spPayOrder")){
            HistoricVariableInstance variable= historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstance.getId()).variableName("serviceType").singleResult();
            String serviceType = "";
            if(variable!=null){
                serviceType = variable.getValue().toString();
            }
            fobService.updateApprovaResult(processInstance.getBusinessKey(),-1,processInstance.getProcessDefinitionKey(),serviceType);
        }else if(processInstance.getProcessDefinitionKey().startsWith("spYearPlan")){
            spDispatchSchemeDetailService.yearPlanSchemeApproveBack(processInstance.getBusinessKey(),2);
        } else if(processInstance.getProcessDefinitionKey().startsWith("spDispatchScheme")){
            spDispatchService.dispatchSchemeApproveBack(processInstance.getBusinessKey(),2);
        } else if(processInstance.getProcessDefinitionKey().startsWith("spDispatchScheme")){
            Map<String,Object> params =  new HashMap<>();
            List<HistoricVariableInstance> variableInstances = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstance.getId()).list();
            for(HistoricVariableInstance variableInstance:variableInstances){
                params.put(variableInstance.getVariableName(),variableInstance.getValue());
            }
            spArrangeSchemeService.arrangeSchemeApproveBack(params,Long.parseLong(processInstance.getBusinessKey()),2);
        }else if(processInstance.getProcessDefinitionKey().equals(BpmInstanceServiceApi.SYSTEM_DELETE_BPM_KEY)){
            String module = "";
            Integer serviceType = null;
            List<HistoricVariableInstance> variableInstances = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstance.getId()).list();
            for(HistoricVariableInstance variableInstance:variableInstances){
                if(variableInstance.getVariableName().equals("module")){
                    module = variableInstance.getValue().toString();
                }
                if(variableInstance.getVariableName().equals("serviceType")){
                    serviceType = Integer.parseInt(variableInstance.getValue().toString());
                }
            }
            if(module.equals("con")){
                //Integer serviceType = (Integer) params.get("serviceType");
                conBpmResultService.deleteConResult(processInstance.getBusinessKey(),2,processInstance.getProcessDefinitionKey(),serviceType);
            }else if(module.equals("payOrder")){
                if(serviceType==1){
                    SpPaymentOrder spPaymentOrder = spPaymentOrderService.getById(processInstance.getBusinessKey());
                    spPaymentOrder.setApproverStatus(-1);
                    spPaymentOrderService.updateById(spPaymentOrder);
                }
            }else if(module.equals("shipCrew")){
                if(serviceType.equals("1")){
                    smShipCrewService.cancelDelete(processInstance.getBusinessKey(),-1);
                }
            }else if(module.equals("shipReport")){
                if(serviceType.equals("1")){
                    smShipReportService.cancelDelete(processInstance.getBusinessKey(),-1);
                }
            }else if(module.equals("spOverhaul")) {
                if (serviceType == 1) {
                    spOverhaulService.cancelDelete(processInstance.getBusinessKey(), -1);
                }
            }
        }
    }

    @Autowired
    SpFobSubleaseStartService spFobSubleaseStartService;

    @Override
    public JsonResult<String> createSubleassProcessInstance(BpmStartVO bpmStartVO) {
        ConShipping conShipping = conShippingService.getById(bpmStartVO.getBusinessKey());
        List<SpFobSublease> list = spFobSubleaseService.list(new LambdaQueryWrapper<SpFobSublease>().eq(SpFobSublease::getConId,bpmStartVO.getBusinessKey()).ne(SpFobSublease::getStatus,2));
        if(list.size()>0){
            throw new BusException("当前业务已发起流程，不可重复发起",BaseResultCode.GENERAL_ERROR);
        }
        if(conShipping.getContractType()==4){
            bpmStartVO.setProcessKey("FOB005v1");
        }else if(conShipping.getContractType()==2){
            bpmStartVO.setProcessKey("FOB006v1");
        }else if(conShipping.getContractType()==3){
            bpmStartVO.setProcessKey("FOB007v1");
        }else if(conShipping.getContractType()==1){
            bpmStartVO.setProcessKey("FOB008v1");
        }
        if(bpmStartVO.getProcessKey()==null){
            throw new BusException("当前合理流程未开发",BaseResultCode.GENERAL_ERROR);
        }
        ProcessDefinition processDefinition =repositoryService.createProcessDefinitionQuery().processDefinitionKey(bpmStartVO.getProcessKey()).latestVersion().singleResult();
        if(processDefinition == null){
            return JsonResult.failed("流程定义不存在，请联系管理员确认后重新发起");
        }
        if(bpmStartVO.getAssigner()==null){
            bpmStartVO.setAssigner(SecurityUtils.getUsername()+"");
        }
        if(bpmStartVO.getAssigner()==null){
            bpmStartVO.setAssigner("test001");
        }
        Map<String,Object> params = new HashMap<>();
        params.put("assigeners",bpmStartVO.getAssigner());
        params.put("initiator", SecurityUtils.getStringUserId());
        params.put("businessKey", bpmStartVO.getBusinessKey());
        if(conShipping!=null){
            Map<String,String> tempMap = JsonUtils.jsonToMap(JsonUtils.objectToJson(conShipping),String.class);
            params.putAll(tempMap);
        }
        params.put("_FLOWABLE_SKIP_EXPRESSION_ENABLED", true);
        ProcessInstance instance = runtimeService.startProcessInstanceById(processDefinition.getId(), bpmStartVO.getBusinessKey().toString(), params);
        Task firstTask = taskService.createTaskQuery().processInstanceId(instance.getId()).active().singleResult();
        if(firstTask!=null){ //自动完成第一个任务
            taskService.setAssignee(firstTask.getId(),SecurityUtils.getUsername());
            taskService.complete(firstTask.getId());
            SpFobSubleaseStart spFobSubleaseStart = new SpFobSubleaseStart();
            spFobSubleaseStart.setProceeInstanceId(instance.getId());
            spFobSubleaseStart.setTaskId(firstTask.getId());
            spFobSubleaseStart.setAddAssigeners(bpmStartVO.getAssigner());
            spFobSubleaseStart.setSchemeDetailId(bpmStartVO.getBusinessKey());
            spFobSubleaseStart.setStatus(1);
            /*List<ConFiles> conFiles = conFilesService.list(new LambdaQueryWrapper<ConFiles>().eq(ConFiles::getConId,bpmStartVO.getBusinessKey()).eq(ConFiles::getFileType,1));
            List<String> conFile = new ArrayList<>();
            if(conFiles!=null && conFiles.size()>0){
                for(ConFiles conFiles1:conFiles){
                    conFile.add(conFiles1.getUrl());
                }
            }*/
            ObjectMapper objectMapper = new ObjectMapper();
            ArrayNode arrayNode = objectMapper.createArrayNode();
            ObjectNode node =  objectMapper.createObjectNode();
            node.put("contractName",conShipping.getContractName());
            node.put("url","/shipAContractInfo?tab=1&id="+bpmStartVO.getBusinessKey());
            arrayNode.add(node);
            spFobSubleaseStart.setConFile(JsonUtils.objectToJson(arrayNode));
            spFobSubleaseStartService.save(spFobSubleaseStart);
        }
        // 设置流程名字
        runtimeService.setProcessInstanceName(instance.getId(), processDefinition.getName());
        // 绑定方案单据
        SpFobSublease execute = new SpFobSublease();
        BeanUtils.copyProperties(conShipping,execute);
        execute.setId(null);
        execute.setConId(conShipping.getId());
        execute.setProcessInstanceId(instance.getId());
        execute.setAssigeners(bpmStartVO.getAssigner());
        execute.setStatus(0);
        spFobSubleaseService.save(execute);
        return JsonResult.success();
    }


    public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId) {
        HistoricProcessInstance historicProcessInstance =
                historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        if (Objects.isNull(historicProcessInstance)) {
            throw new FlowableObjectNotFoundException("流程实例不存在: " + processInstanceId);
        }
        return historicProcessInstance;
    }
}
